import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:gzmall_app/login/login.dart';
import 'package:package_info/package_info.dart';
import 'dart:convert';
import 'api.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:gzmall_app/common/toast_util.dart';
import 'package:gzmall_app/model/user.dart';
import 'package:flutter/material.dart';

//要查网络请求的日志可以使用过滤<net>
class NetUtil {
  static const String GET = "get";
  static const String POST = "post";
  static const String PUT = "put";
  static const String DELETE = "delete";

  //get请求
  static void get(BuildContext context, String url, Function callBack,
      {params,
      Function errorCallBack,
      bool isInterceptError = true,
      bool isShowLoading = false}) async {
    _request(context, Api.baseUrl + url, callBack,
        method: GET,
        queryParameters: params,
        errorCallBack: errorCallBack,
        isInterceptError: isInterceptError,
        isShowLoading: isShowLoading);
  }

  //put请求
  static void put(BuildContext context, String url, Function callBack,
      {params,
      Function errorCallBack,
      bool isInterceptError = true,
      bool isShowLoading = false,
      queryParameters}) async {
    _request(context, Api.baseUrl + url, callBack,
        method: PUT,
        data: params,
        queryParameters: queryParameters,
        errorCallBack: errorCallBack,
        isInterceptError: isInterceptError,
        isShowLoading: isShowLoading);
  }

  //put请求
  static void delete(BuildContext context, String url, Function callBack,
      {params,
      Function errorCallBack,
      bool isInterceptError = true,
      bool isShowLoading = false,
      queryParameters}) async {
    _request(context, Api.baseUrl + url, callBack,
        method: DELETE,
        data: params,
        queryParameters: queryParameters,
        errorCallBack: errorCallBack,
        isInterceptError: isInterceptError,
        isShowLoading: isShowLoading);
  }

  //post请求
  static void post(BuildContext context, String url, Function callBack,
      {params,
      Function errorCallBack,
      bool isInterceptError = true,
      bool isShowLoading = false,
      queryParameters}) async {
    _request(context, Api.baseUrl + url, callBack,
        method: POST,
        data: params,
        queryParameters: queryParameters,
        errorCallBack: errorCallBack,
        isInterceptError: isInterceptError,
        isShowLoading: isShowLoading);
  }

  //具体的还是要看返回数据的基本结构
  //公共代码部分
  static void _request(BuildContext context, String url, Function callBack,
      {String method,
      data,
      Function errorCallBack,
      bool isInterceptError = true,
      bool isShowLoading = false,
      queryParameters}) async {
    if (method == GET) {
      if (data != null) {
        data['per'] = data['per'] ?? Api.pageSize.toString();
      } else {
        data = {"per": Api.pageSize.toString()};
      }
      if (queryParameters != null) {
        queryParameters['per'] =
            queryParameters['per'] ?? Api.pageSize.toString();
      } else {
        queryParameters = {"per": Api.pageSize.toString()};
      }
    }
    bool isShowingDialog = false;
    if (isShowLoading) {
      isShowingDialog = true;
      showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return SpinKitFadingCircle(
              color: Colors.white,
            );
          });
    }

    // String errorMsg = "";
    // int statusCode;

    Dio dio = Dio();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));
    dio.interceptors
        .add(InterceptorsWrapper(onRequest: (RequestOptions options) {
      options.headers["Accept"] = "*/*";
      options.headers["Authorization"] =
          prefs.getString('user_auth_token') ?? "";
      options.headers["latitude"] = prefs.getString('latitude') ?? "";
      options.headers["longitude"] = prefs.getString('longitude') ?? "";
      options.headers["adcode"] = prefs.getString('adcode') ?? "";
      options.headers["location"] =
          Uri.encodeComponent(prefs.getString('location') ?? "");
      options.headers["version"] = packageInfo.version ?? "";
      options.headers["platform"] = Platform.isIOS ? "ios" : "android";

      print("<net> request options headers: ${options.headers.toString()}");

      return options;
    }, onResponse: (Response response) {
      if (isShowingDialog) {
        Navigator.of(context).pop();
        isShowingDialog = false;
      }

      return response;
    }, onError: (DioError e) {
      if (isShowingDialog) {
        Navigator.of(context).pop();
        isShowingDialog = false;
      }

      if (isInterceptError) {
        int statusCode = e.response?.statusCode;
        if (statusCode != null) {
          switch (statusCode) {
            case 401:
              ToastUtil.showMessageToast("登录超时");
              User.cleanUserToken();
              if (!User.isInLogin) {
                User.isInLogin = true;
                Navigator.of(context).pushNamed('/login_page');
              }
              break;
            default:
              if (e.message != null && e.message.isNotEmpty) {
                ToastUtil.showMessageToast(e.message);
              }
              break;
          }
        }
      }

      return e;
    }));

    if (method == GET) {
      dio.get(url, queryParameters: queryParameters).then((res) {
        _handRes(res, errorCallBack, callBack);
      }).catchError((exception) {
        _handError(errorCallBack, exception.toString(), false);
      });
    } else if (method == POST) {
      dio.post(url, data: data, queryParameters: queryParameters).then((res) {
        _handRes(res, errorCallBack, callBack);
      }).catchError((exception) {
        _handError(errorCallBack, exception.toString(), false);
      });
    } else if (method == PUT) {
      dio.put(url, data: data, queryParameters: queryParameters).then((res) {
        _handRes(res, errorCallBack, callBack);
      }).catchError((exception) {
        _handError(errorCallBack, exception.toString(), false);
      });
    } else if (method == DELETE) {
      dio.delete(url, data: data, queryParameters: queryParameters).then((res) {
        _handRes(res, errorCallBack, callBack);
      }).catchError((exception) {
        _handError(errorCallBack, exception.toString(), false);
      });
    }

    // try {
    //   Response response;

    //   if (method == GET) {
    //     response = await dio.get(url, queryParameters: queryParameters);
    //   } else if (method == POST) {
    //     response =
    //         await dio.post(url, data: data, queryParameters: queryParameters);
    //   } else if (method == PUT) {
    //     response =
    //         await dio.put(url, data: data, queryParameters: queryParameters);
    //   } else if (method == DELETE) {
    //     response =
    //         await dio.delete(url, data: data, queryParameters: queryParameters);
    //   }

    //   statusCode = response.statusCode;

    //   //处理错误部分
    //   if (statusCode < 0) {
    //     errorMsg = "网络请求错误,状态码:" + statusCode.toString();
    //     _handError(errorCallBack, errorMsg, true);
    //     return;
    //   }

    //   bool result = response.data.toString().contains("result")
    //       ? response.data["result"]
    //       : false;
    //   var message = response.data.toString().contains("result")
    //       ? response.data["message"]
    //       : "";

    //   if (result) {
    //     if (callBack != null) {
    //       var data = response.data.toString().contains("data")
    //           ? response.data["data"]
    //           : "";
    //       callBack(data, message);
    //     }
    //   } else {
    //     errorMsg = message;
    //     _handError(errorCallBack, errorMsg, true);
    //     return;
    //   }
    // } catch (exception) {
    //   _handError(errorCallBack, exception.toString(), false);
    // }
  }

  static void _handRes(response, errorCallBack, callBack) {
    String errorMsg = "";
    int statusCode;

    statusCode = response.statusCode;

    //处理错误部分
    if (statusCode < 0) {
      errorMsg = "网络请求错误,状态码:" + statusCode.toString();
      _handError(errorCallBack, errorMsg, true);
      return;
    }

    bool result = response.data.toString().contains("result")
        ? response.data["result"]
        : false;
    var message = response.data.toString().contains("result")
        ? response.data["message"]
        : "";

    if (result) {
      if (callBack != null) {
        var data = response.data.toString().contains("data")
            ? response.data["data"]
            : "";
        callBack(data, message);
      }
    } else {
      errorMsg = message;
      _handError(errorCallBack, errorMsg, true);
      return;
    }
  }

  //处理异常
  static void _handError(
      Function errorCallback, String errorMsg, bool isShowToast) {
    if (isShowToast) {
      ToastUtil.showMessageToast(errorMsg);
    }
    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
    print("<net> _handError errorMsg :" + errorMsg);
  }
}
